Jest to przykład, w którym projekt gitnie pasuje do git-flow-ish przepływu pracy, którego wszyscy używają. Jeśli developwyewidencjonowałeś, oczywiście chcesz cofnąć gałąź funkcji 2-commit, która wprowadziła błąd, a nie wieloletnią wspólną gałąź programistów. To śmieszne, że trzeba to wybrać -m 1.
pkamb
2
Jeszcze jedna sugestia, która nigdy wcześniej mi się nie zdarzyła - jeśli lista zatwierdzeń jednej gałęzi jest niewielka, wygodniej będzie cofnąć poszczególne zatwierdzenia zamiast całej gałęzi zatwierdzeń.
Sridhar Sarnobat
Odpowiedzi:
1152
-mOpcja określa liczbę nadrzędną . Jest tak, ponieważ zatwierdzenie scalania ma więcej niż jednego rodzica, a Git nie wie automatycznie, który rodzic był linią główną, a który rodzic był gałęzią, którą chcesz cofnąć.
Gdy zobaczysz zatwierdzenie scalania w danych wyjściowych git log, zobaczysz jego rodziców wymienionych w wierszu, który zaczyna się od Merge:
commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <[email protected]>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
W tej sytuacji git revert 8f937c6 -m 1dostaniesz drzewo w takim stanie 8989ee0, w jakim ono było , i git revert -m 2przywróci je w stanie, w jakim było 7c6b236.
Aby lepiej zrozumieć identyfikatory nadrzędne, możesz uruchomić:
Podczas przeglądania Google w poszukiwaniu lepszego wyjaśnienia znalazłem ten artykuł, który moim zdaniem wykonał świetną robotę, omawiając szczegóły. Po przeczytaniu odkryłem, że tak naprawdę szukałem polecenia RESET, a następnie wymuszenia. Może pomoże komuś innemu. atlassian.com/git/tutorials/…
git log - łączy się, aby zobaczyć wszystkie połączenia i git log --no-łączy się, aby zobaczyć historię bez połączeń. Scalenie gałęzi przenosi historię połączonych gałęzi do celu i utrudnia
rozszyfrowanie
368
Oto kompletny przykład z nadzieją, że pomoże komuś:
Gdzie <commit-hash>znajduje się skrót zatwierdzenia scalenia, który chcesz przywrócić, a jak podano w wyjaśnieniu tej odpowiedzi , -m 1wskazuje, że chcesz powrócić do drzewa pierwszego rodzica przed scaleniem.
git revert ...Linia zasadniczo dopuszcza zmiany, natomiast druga linia sprawia, że zmiany publiczny popychając je do odległego oddziału.
Wierzyłem, że git revertpolecenie już zatwierdziło utworzony obiekt zatwierdzenia. Aby tak się nie stało, trzeba wprowadzić --no-commitflagę
Delfic
2
Jak wspomniał @Delfic, zatwierdzeniem zarządza już pierwszy wiersz (potrzebowałem: wq, aby go zweryfikować), więc drugi wiersz nie jest konieczny.
eka808
1
to jest mylące. są tylko 2 linie i nie ma git commit .. czy ktoś może edytować.
Jay Random
176
Ben powiedział ci, jak cofnąć zatwierdzenie scalania, ale bardzo ważne jest, abyś zdał sobie z tego sprawę
„... oświadcza, że nigdy nie będziesz chciał, aby zmiany drzewa wprowadzane przez scalanie. W rezultacie późniejsze scalenia przyniosą tylko zmiany drzewa wprowadzone przez zatwierdzenia, które nie są przodkami wcześniej cofniętego scalenia. Może to być lub nie czego chcesz. ” (strona podręcznika git-merge) .
Lista wiadomości article / mailing powiązany ze strony człowieka szczegóły mechanizmów i ustaleń, które są zaangażowane. Upewnij się tylko, że rozumiesz, że jeśli cofniesz zatwierdzenie scalania, nie możesz po prostu ponownie scalić gałęzi później i oczekiwać, że te same zmiany wrócą.
Ale możesz cofnąć cofnięcie, aby je odzyskać, jeśli naprawdę jest potrzebne.
dalej
5
Dzięki. Bardzo przydatna jest znajomość przypadku cofania scalania - powiedzmy, z powodu błędu - a następnie ponownego łączenia całej gałęzi po naprawieniu błędu, jest częstym zjawiskiem.
Element 10
3
Jeśli jesteś podobny do mnie, a później chciałeś scalenia, możesz cofnąć przywrócenie lub wybrać zmianę, którą cofnąłeś.
UnitasBrooks
W mojej sytuacji uderzyłem w konieczność „cofnięcia cofnięcia”, aby uzyskać problem z powrotem zmian. Zbieranie wiśni może być lepszym sposobem? Spróbuję następnym razem ...
Steven Anderson
79
Możesz wykonać następujące kroki, aby przywrócić nieprawidłowe zatwierdzenie (-a) lub zresetować zdalną gałąź z powrotem do poprawnego HEAD / state.
wypłata zdalnego oddziału do lokalnego repozytorium. git checkout development
skopiuj skrót zatwierdzenia (tj. identyfikator zatwierdzenia bezpośrednio przed niewłaściwym zatwierdzeniem) z dziennika git
git log -n5
wynik:
popełnić 7cd42475d6f95f5896b6f02e902efab0b70e8038 "Merge branch 'źle-commit' do 'rozwoju'"
popełnienia f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "jest to błędne popełnić"
popełnić 3779ab50e72908da92d2cfcd72256d7a09f446ba "to jest poprawna commit"
zresetuj gałąź do skrótu zatwierdzenia skopiowanego w poprzednim kroku git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
uruchom, git statusaby wyświetlić wszystkie zmiany, które były częścią niewłaściwego zatwierdzenia.
po prostu uruchom, git reset --hardaby cofnąć wszystkie te zmiany.
zmuszaj lokalny oddział do zdalnej obsługi i zauważ, że twoja historia zatwierdzeń jest czysta, jak była przed zanieczyszczeniem. git push -f origin development
co jeśli w międzyczasie 20 programistów przeprowadziło najnowsze połączenie deweloperów?
Ewoks
2
Nie wymuszałbym forsowania gałęzi programistycznej, gdy w zespole jest 20 programistów korzystających z tej gałęzi. :) W takim przypadku dobrze jest po prostu wykonać zatwierdzenie przywracania.
ssasi
4
Jest to bardzo dobre rozwiązanie, gdy pracujesz sam lub jesteś pewien, że żaden inny deweloper nie wycofał się z popełnianych przez ciebie zobowiązań
Wskazówka: jeśli robisz to w swojej firmie, możesz nie mieć pozwolenia.
eneski
3
nigdy nie rób push -fwspólnego repo
Baptiste Mille-Mathias
17
Czasami najskuteczniejszym sposobem wycofania jest wycofanie się i zastąpienie.
git log
Skorzystaj z drugiego skrótu zatwierdzenia (pełnego skrótu, tego, do którego chcesz przywrócić, przed podanym błędem), a następnie stamtąd dokonaj reorganizacji.
git checkout -b newbranch <HASH>
Następnie usuń starą gałąź, skopiuj newbranch na jego miejsce i ponownie uruchom stamtąd.
Jeśli został nadany, usuń starą gałąź ze wszystkich repozytoriów, popchnij ponownie gałąź do najbardziej centralnej i pociągnij ją z powrotem do wszystkich.
Ostrzeżenie przed transmisją powinno być naprawdę wyraźniejsze na temat tego, jak okropny jest to pomysł. Spowoduje to uszkodzenie wszystkich wersji tej gałęzi i jest naprawdę przydatne, jeśli pracujesz ze zdalnym repozytorium (github / bitbucket), do którego tylko Ty masz dostęp.
RobbyD
Nie tak źle, jak spychanie zmodyfikowanych plików konfiguracyjnych w dół strumienia do produkcji. Nie ulegnie uszkodzeniu, jest to tylko rebranżacja wcześniejszego zatwierdzenia, więc jest to okrągły sposób na przeniesienie wskaźnika gałęzi do wcześniejszej wersji. Mam nadzieję, że wpłynie to tylko na lokalne repozytorium
ppostma1,
5
Jeśli chcesz cofnąć mergezatwierdzenie, oto co musisz zrobić.
Najpierw sprawdź, git logaby znaleźć identyfikator zatwierdzenia scalania. Znajdziesz także wiele identyfikatorów nadrzędnych powiązanych ze scaleniem (patrz zdjęcie poniżej).
Zanotuj identyfikator zatwierdzenia scalania pokazany na żółto. Identyfikatory nadrzędne to te zapisane w następnym wierszu jako Merge: parent1 parent2. Teraz...
Krótka historia:
Przełącz na gałąź, na której dokonano scalenia. Następnie po prostu zrób to, git revert <merge commit id> -m 1co otworzy vikonsolę do wprowadzania komunikatu zatwierdzenia. Napisz, zapisz, wyjdź, gotowe!
Długa historia:
Przełącz na gałąź, na której dokonano scalenia. W moim przypadku jest to testgałąź i staram się ją usunąć feature/analytics-v3.
git revertto polecenie, które cofa każde zatwierdzenie. Ale przy cofnięciu mergezatwierdzenia jest paskudna sztuczka . Musisz wpisać -mflagę, inaczej się nie powiedzie. Odtąd musisz zdecydować, czy chcesz przywrócić swój oddział i sprawić, by wyglądał dokładnie tak, jak był parent1lub parent2za pośrednictwem:
git revert <merge commit id> -m 1(wraca do parent2)
git revert <merge commit id> -m 2(wraca do parent1)
Możesz zalogować tych rodziców, aby dowiedzieć się, którą drogą chcesz iść, i to jest przyczyną całego zamieszania.
Wszystkie odpowiedzi dotyczyły już większości rzeczy, ale dodam 5 centów. W skrócie cofnięcie zatwierdzenia scalania jest dość proste:
git revert -m 1 <commit-hash>
Jeśli masz uprawnienia, możesz przepchnąć je bezpośrednio do gałęzi „master”, w przeciwnym razie po prostu wypchnij je do swojej gałęzi „revert” i utwórz żądanie ściągnięcia.
Odkryłem, że utworzenie odwrotnej łatki między dwoma znanymi punktami końcowymi i zastosowanie tej łatki byłoby skuteczne. Zakłada się, że utworzyłeś migawki (tagi) poza gałęzią master, a nawet kopią zapasową gałęzi master, powiedz master_bk_01012017.
Powiedzmy, że gałąź kodu, którą scaliłeś w master, to mojaoddział.
Mistrz kasy.
Utwórz pełną binarną odwrotną łatkę między master a twoją kopią zapasową.
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
Sprawdź poprawkę
git apply --check myrevert.patch
Zastosuj łatkę z podpisem
git am --signoff < myrevert.patch
Jeśli będziesz musiał ponownie wprowadzić ten kod, gdy zostanie on naprawiony, musisz odłączyć cofniętego mastera i sprawdzić gałąź fix
git branch mycodebranch_fixgit checkout mycodebranch_fix
Tutaj musisz znaleźć klucz SHA do przywrócenia i przywrócić przywrócenie
git revert [SHA]
Teraz możesz użyć swojej poprawki mycodebranch_fix, aby naprawić problemy, zatwierdzić i ponownie połączyć w master po zakończeniu.
Prawidłowo oznaczona odpowiedź działała dla mnie, ale musiałem poświęcić trochę czasu, aby ustalić, co się dzieje. Postanowiłem więc dodać odpowiedź, podając proste, proste kroki w przypadku takich przypadków jak mój.
Powiedzmy, że mamy oddziały A i B .. Połączyłeś oddział A w oddział B i odepchnąłeś oddział B do siebie, więc teraz scalenie jest jego częścią. Ale chcesz wrócić do ostatniego zatwierdzenia przed scaleniem .. Co zrobić ty robisz?
Przejdź do folderu głównego git (zwykle folder projektu) i użyj git log
Zobaczysz historię ostatnich zatwierdzeń - zatwierdzenia mają właściwości zatwierdzenia / autora / daty, podczas gdy scalenia mają także właściwość scalania - więc widzisz je w następujący sposób:
Użyj git log <parentHashA>i git log <parentHashB>- zobaczysz historię zatwierdzeń tych oddziałów nadrzędnych - pierwsze zatwierdzenia na liście są najnowsze
Wybierz <commitHash>żądane zatwierdzenie, przejdź do folderu głównego git i użyj git checkout -b <newBranchName> <commitHash>- utworzy nowy oddział, zaczynając od ostatniego zatwierdzenia wybranego przed scaleniem. Voila, gotowe!
Problem ten napotkałem również w przypadku PR, który został połączony z gałęzią główną repozytorium GitHub.
Ponieważ chciałem po prostu zmodyfikować niektóre zmodyfikowane pliki, ale nie cały zmiany PR przyniósł musiałem z .amendmerge commitgit commit --am
Kroki:
Przejdź do gałęzi, którą chcesz zmienić / przywrócić niektóre zmodyfikowane pliki
Wprowadź wymagane zmiany zgodnie ze zmodyfikowanymi plikami
uruchomić git add *lubgit add <file>
uruchom git commit --ami sprawdź poprawność
biegać git push -f
Dlaczego to interesujące:
Utrzymuje autor PR niezmieniony
Nie łamie drzewa git
Zostaniesz oznaczony jako osoba zatwierdzająca (autor zatwierdzenia scalania pozostanie niezmieniony)
Git działa tak, jakbyś rozwiązał konflikty, usunie / zmieni kod w zmodyfikowanych plikach, tak jakbyś ręcznie powiedział GitHubowi, aby nie scalał go tak, jak jest
Znalazłem dobre wyjaśnienie dotyczące sposobu cofnięcia scalenia z tego linku i skopiowałem wklejone wyjaśnienie poniżej i byłoby pomocne na wypadek, gdyby poniższy link nie działał.
Jak przywrócić wadliwe scalenie Alan ([email protected]) powiedział:
Mam gałąź główną. Mamy gałąź, nad którą pracują niektórzy programiści. Twierdzą, że jest gotowy. Scalamy go z gałęzią master. Coś psuje, więc cofamy scalanie. Wprowadzają zmiany w kodzie. doprowadzają go do punktu, w którym mówią, że jest w porządku, a my ponownie się scalamy. Po zbadaniu okazuje się, że zmiany kodu dokonane przed przywróceniem nie znajdują się w gałęzi master, ale zmiany kodu po nim są w gałęzi master. i poprosił o pomoc w wyjściu z tej sytuacji.
Historia natychmiast po „przywróceniu scalenia” wyglądałaby następująco:
---o---o---o---M---x---x---W
/
---A---B
gdzie A i B znajdują się po stronie rozwoju, który nie był tak dobry, M jest scaleniem, które przenosi te przedwczesne zmiany do linii głównej, x są zmianami niezwiązanymi z tym, co zrobiła gałąź boczna i już dokonała na linii głównej, a W jest „ revert of the merge M "(czy W nie wygląda M na odwrót?). IOW, „diff W ^ .. W” jest podobne do „diff -RM ^ .. M”.
Takie „cofnięcie” scalenia można wykonać za pomocą:
$ git revert -m 1 M
Po tym, jak twórcy bocznej gałęzi naprawią swoje błędy, historia może wyglądać następująco:
gdzie C i D mają naprawić to, co zostało zepsute w A i B, i możesz już mieć inne zmiany w linii głównej po W.
Jeśli scalisz zaktualizowaną gałąź boczną (z D na jej końcu), żadna ze zmian dokonanych w A lub B nie nastąpi, ponieważ zostały cofnięte przez W. Tak właśnie widział Alan.
Linus wyjaśnia sytuację:
Cofnięcie zwykłego zatwierdzenia po prostu skutecznie anuluje to, co zrobił, i jest dość proste. Ale cofnięcie zatwierdzenia scalania powoduje również cofnięcie danych, które zmieniło zatwierdzenie, ale nie ma absolutnie żadnego wpływu na historię , jaką miało scalenie. Zatem scalanie będzie nadal istniało i nadal będzie postrzegane jako łączenie dwóch gałęzi razem, a przyszłe połączenia zobaczą to scalenie jako ostatni wspólny stan - a przywrócenie, które odwróciło wprowadzone scalenie, nie wpłynie na to wcale. Tak więc „cofnięcie” cofa zmiany danych, ale tak naprawdę nie jest„cofnij” w tym sensie, że nie cofnie to wpływu zatwierdzenia na historię repozytorium. Jeśli więc myślisz o „cofnięciu” jako „cofnięciu”, to zawsze będziesz tęsknił za tą częścią powrotów. Tak, usuwa dane, ale nie, nie cofa historii. W takiej sytuacji powinieneś najpierw przywrócić poprzednią wersję, dzięki czemu historia wyglądałaby tak:
Jak wspomniał Ryan, git revertmoże to utrudnić połączenie, więc git revertmoże nie być to, czego chcesz. Zauważyłem, że użycie git reset --hard <commit-hash-prior-to-merge>polecenia jest bardziej przydatne tutaj.
Po wykonaniu części twardego resetu możesz następnie wymusić wypchnięcie do zdalnej gałęzi, czyli git push -f <remote-name> <remote-branch-name>tam, gdzie <remote-name>często jest ona nazywana origin. Od tego momentu możesz ponownie połączyć, jeśli chcesz.
Wszystko, co wymaga użycia siły jest złym pomysłem, chyba że jesteś jedynym, który używa repozytorium i wiesz dokładnie, co robisz. Cofanie za pomocą git revert, a następnie ewentualnie cofanie za pomocą git revert (jeśli musisz przywrócić rzeczy z powrotem) jest znacznie bezpieczniejszą alternatywą.
git
nie pasuje dogit-flow
-ish przepływu pracy, którego wszyscy używają. Jeślidevelop
wyewidencjonowałeś, oczywiście chcesz cofnąć gałąź funkcji 2-commit, która wprowadziła błąd, a nie wieloletnią wspólną gałąź programistów. To śmieszne, że trzeba to wybrać-m 1
.Odpowiedzi:
-m
Opcja określa liczbę nadrzędną . Jest tak, ponieważ zatwierdzenie scalania ma więcej niż jednego rodzica, a Git nie wie automatycznie, który rodzic był linią główną, a który rodzic był gałęzią, którą chcesz cofnąć.Gdy zobaczysz zatwierdzenie scalania w danych wyjściowych
git log
, zobaczysz jego rodziców wymienionych w wierszu, który zaczyna się odMerge
:W tej sytuacji
git revert 8f937c6 -m 1
dostaniesz drzewo w takim stanie8989ee0
, w jakim ono było , igit revert -m 2
przywróci je w stanie, w jakim było7c6b236
.Aby lepiej zrozumieć identyfikatory nadrzędne, możesz uruchomić:
i
źródło
8989ee0
,7c6b236
, który z nich pójść. Jak mam to zrozumieć?git log 8989ee0
igit log 7c6b236
powinieneś znać odpowiedź.Oto kompletny przykład z nadzieją, że pomoże komuś:
Gdzie
<commit-hash>
znajduje się skrót zatwierdzenia scalenia, który chcesz przywrócić, a jak podano w wyjaśnieniu tej odpowiedzi ,-m 1
wskazuje, że chcesz powrócić do drzewa pierwszego rodzica przed scaleniem.git revert ...
Linia zasadniczo dopuszcza zmiany, natomiast druga linia sprawia, że zmiany publiczny popychając je do odległego oddziału.źródło
git revert
polecenie już zatwierdziło utworzony obiekt zatwierdzenia. Aby tak się nie stało, trzeba wprowadzić--no-commit
flagęBen powiedział ci, jak cofnąć zatwierdzenie scalania, ale bardzo ważne jest, abyś zdał sobie z tego sprawę
Lista wiadomości article / mailing powiązany ze strony człowieka szczegóły mechanizmów i ustaleń, które są zaangażowane. Upewnij się tylko, że rozumiesz, że jeśli cofniesz zatwierdzenie scalania, nie możesz po prostu ponownie scalić gałęzi później i oczekiwać, że te same zmiany wrócą.
źródło
Możesz wykonać następujące kroki, aby przywrócić nieprawidłowe zatwierdzenie (-a) lub zresetować zdalną gałąź z powrotem do poprawnego HEAD / state.
git checkout development
skopiuj skrót zatwierdzenia (tj. identyfikator zatwierdzenia bezpośrednio przed niewłaściwym zatwierdzeniem) z dziennika git
git log -n5
zresetuj gałąź do skrótu zatwierdzenia skopiowanego w poprzednim kroku
git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
git status
aby wyświetlić wszystkie zmiany, które były częścią niewłaściwego zatwierdzenia.git reset --hard
aby cofnąć wszystkie te zmiany.git push -f origin development
źródło
źródło
Aby utrzymać dziennik w czystości, ponieważ nic się nie wydarzyło (z pewnymi wadami tego podejścia (z powodu push-f)):
„commit-hash-before-merge” pochodzi z logu (git log) po scaleniu.
źródło
push -f
wspólnego repoCzasami najskuteczniejszym sposobem wycofania jest wycofanie się i zastąpienie.
git log
Skorzystaj z drugiego skrótu zatwierdzenia (pełnego skrótu, tego, do którego chcesz przywrócić, przed podanym błędem), a następnie stamtąd dokonaj reorganizacji.
git checkout -b newbranch <HASH>
Następnie usuń starą gałąź, skopiuj newbranch na jego miejsce i ponownie uruchom stamtąd.
Jeśli został nadany, usuń starą gałąź ze wszystkich repozytoriów, popchnij ponownie gałąź do najbardziej centralnej i pociągnij ją z powrotem do wszystkich.
źródło
Jeśli chcesz cofnąć
merge
zatwierdzenie, oto co musisz zrobić.git log
aby znaleźć identyfikator zatwierdzenia scalania. Znajdziesz także wiele identyfikatorów nadrzędnych powiązanych ze scaleniem (patrz zdjęcie poniżej).Zanotuj identyfikator zatwierdzenia scalania pokazany na żółto. Identyfikatory nadrzędne to te zapisane w następnym wierszu jako
Merge: parent1 parent2
. Teraz...Krótka historia:
git revert <merge commit id> -m 1
co otworzyvi
konsolę do wprowadzania komunikatu zatwierdzenia. Napisz, zapisz, wyjdź, gotowe!Długa historia:
Przełącz na gałąź, na której dokonano scalenia. W moim przypadku jest to
test
gałąź i staram się ją usunąćfeature/analytics-v3
.git revert
to polecenie, które cofa każde zatwierdzenie. Ale przy cofnięciumerge
zatwierdzenia jest paskudna sztuczka . Musisz wpisać-m
flagę, inaczej się nie powiedzie. Odtąd musisz zdecydować, czy chcesz przywrócić swój oddział i sprawić, by wyglądał dokładnie tak, jak byłparent1
lubparent2
za pośrednictwem:git revert <merge commit id> -m 1
(wraca doparent2
)git revert <merge commit id> -m 2
(wraca doparent1
)Możesz zalogować tych rodziców, aby dowiedzieć się, którą drogą chcesz iść, i to jest przyczyną całego zamieszania.
źródło
Wszystkie odpowiedzi dotyczyły już większości rzeczy, ale dodam 5 centów. W skrócie cofnięcie zatwierdzenia scalania jest dość proste:
Jeśli masz uprawnienia, możesz przepchnąć je bezpośrednio do gałęzi „master”, w przeciwnym razie po prostu wypchnij je do swojej gałęzi „revert” i utwórz żądanie ściągnięcia.
Więcej przydatnych informacji na ten temat można znaleźć tutaj: https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html
źródło
Odkryłem, że utworzenie odwrotnej łatki między dwoma znanymi punktami końcowymi i zastosowanie tej łatki byłoby skuteczne. Zakłada się, że utworzyłeś migawki (tagi) poza gałęzią master, a nawet kopią zapasową gałęzi master, powiedz master_bk_01012017.
Powiedzmy, że gałąź kodu, którą scaliłeś w master, to mojaoddział.
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
git apply --check myrevert.patch
git am --signoff < myrevert.patch
git branch mycodebranch_fix
git checkout mycodebranch_fix
git revert [SHA]
źródło
Prawidłowo oznaczona odpowiedź działała dla mnie, ale musiałem poświęcić trochę czasu, aby ustalić, co się dzieje. Postanowiłem więc dodać odpowiedź, podając proste, proste kroki w przypadku takich przypadków jak mój.
Powiedzmy, że mamy oddziały A i B .. Połączyłeś oddział A w oddział B i odepchnąłeś oddział B do siebie, więc teraz scalenie jest jego częścią. Ale chcesz wrócić do ostatniego zatwierdzenia przed scaleniem .. Co zrobić ty robisz?
git log
Zobaczysz historię ostatnich zatwierdzeń - zatwierdzenia mają właściwości zatwierdzenia / autora / daty, podczas gdy scalenia mają także właściwość scalania - więc widzisz je w następujący sposób:
commit: <commitHash> Merge: <parentHashA> <parentHashB> Author: <author> Date: <date>
Użyj
git log <parentHashA>
igit log <parentHashB>
- zobaczysz historię zatwierdzeń tych oddziałów nadrzędnych - pierwsze zatwierdzenia na liście są najnowsze<commitHash>
żądane zatwierdzenie, przejdź do folderu głównego git i użyjgit checkout -b <newBranchName> <commitHash>
- utworzy nowy oddział, zaczynając od ostatniego zatwierdzenia wybranego przed scaleniem. Voila, gotowe!źródło
git doc o git revert -m podaj link dokładnie to wyjaśnij: https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt
źródło
Problem ten napotkałem również w przypadku PR, który został połączony z gałęzią główną repozytorium GitHub.
Ponieważ chciałem po prostu zmodyfikować niektóre zmodyfikowane pliki, ale nie cały zmiany PR przyniósł musiałem z .
amend
merge commit
git commit --am
Kroki:
git add *
lubgit add <file>
git commit --am
i sprawdź poprawnośćgit push -f
Dlaczego to interesujące:
źródło
Znalazłem dobre wyjaśnienie dotyczące sposobu cofnięcia scalenia z tego linku i skopiowałem wklejone wyjaśnienie poniżej i byłoby pomocne na wypadek, gdyby poniższy link nie działał.
Jak przywrócić wadliwe scalenie Alan ([email protected]) powiedział:
Mam gałąź główną. Mamy gałąź, nad którą pracują niektórzy programiści. Twierdzą, że jest gotowy. Scalamy go z gałęzią master. Coś psuje, więc cofamy scalanie. Wprowadzają zmiany w kodzie. doprowadzają go do punktu, w którym mówią, że jest w porządku, a my ponownie się scalamy. Po zbadaniu okazuje się, że zmiany kodu dokonane przed przywróceniem nie znajdują się w gałęzi master, ale zmiany kodu po nim są w gałęzi master. i poprosił o pomoc w wyjściu z tej sytuacji.
Historia natychmiast po „przywróceniu scalenia” wyglądałaby następująco:
gdzie A i B znajdują się po stronie rozwoju, który nie był tak dobry, M jest scaleniem, które przenosi te przedwczesne zmiany do linii głównej, x są zmianami niezwiązanymi z tym, co zrobiła gałąź boczna i już dokonała na linii głównej, a W jest „ revert of the merge M "(czy W nie wygląda M na odwrót?). IOW, „diff W ^ .. W” jest podobne do „diff -RM ^ .. M”.
Takie „cofnięcie” scalenia można wykonać za pomocą:
$ git revert -m 1 M Po tym, jak twórcy bocznej gałęzi naprawią swoje błędy, historia może wyglądać następująco:
gdzie C i D mają naprawić to, co zostało zepsute w A i B, i możesz już mieć inne zmiany w linii głównej po W.
Jeśli scalisz zaktualizowaną gałąź boczną (z D na jej końcu), żadna ze zmian dokonanych w A lub B nie nastąpi, ponieważ zostały cofnięte przez W. Tak właśnie widział Alan.
Linus wyjaśnia sytuację:
Cofnięcie zwykłego zatwierdzenia po prostu skutecznie anuluje to, co zrobił, i jest dość proste. Ale cofnięcie zatwierdzenia scalania powoduje również cofnięcie danych, które zmieniło zatwierdzenie, ale nie ma absolutnie żadnego wpływu na historię , jaką miało scalenie. Zatem scalanie będzie nadal istniało i nadal będzie postrzegane jako łączenie dwóch gałęzi razem, a przyszłe połączenia zobaczą to scalenie jako ostatni wspólny stan - a przywrócenie, które odwróciło wprowadzone scalenie, nie wpłynie na to wcale. Tak więc „cofnięcie” cofa zmiany danych, ale tak naprawdę nie jest„cofnij” w tym sensie, że nie cofnie to wpływu zatwierdzenia na historię repozytorium. Jeśli więc myślisz o „cofnięciu” jako „cofnięciu”, to zawsze będziesz tęsknił za tą częścią powrotów. Tak, usuwa dane, ale nie, nie cofa historii. W takiej sytuacji powinieneś najpierw przywrócić poprzednią wersję, dzięki czemu historia wyglądałaby tak:
gdzie Y oznacza cofnięcie W. Takie „cofnięcie cofnięcia” można wykonać za pomocą:
$ git revert W Ta historia (ignorując możliwe konflikty między zmianami W i W..Y) byłaby równoznaczna z brakiem W lub Y w historii:
a ponowne połączenie gałęzi bocznej nie spowoduje konfliktu wynikającego z wcześniejszego cofnięcia i cofnięcia cofnięcia.
Oczywiście zmiany wprowadzone w C i D nadal mogą kolidować z tym, co zostało zrobione przez dowolny z x, ale jest to zwykły konflikt scalania.
źródło
Jak wspomniał Ryan,
git revert
może to utrudnić połączenie, więcgit revert
może nie być to, czego chcesz. Zauważyłem, że użyciegit reset --hard <commit-hash-prior-to-merge>
polecenia jest bardziej przydatne tutaj.Po wykonaniu części twardego resetu możesz następnie wymusić wypchnięcie do zdalnej gałęzi, czyli
git push -f <remote-name> <remote-branch-name>
tam, gdzie<remote-name>
często jest ona nazywanaorigin
. Od tego momentu możesz ponownie połączyć, jeśli chcesz.źródło