Ponowne wykonanie przywróconego scalenia w Git

231

Wpadłem tutaj na pewien problem: miałem 28sw Git gałąź specyficzną dla problemu , którą połączyłem w developgałęzi ogólnej . Okazuje się, że zrobiłem to zbyt szybko, więc użyłem git-revert, aby cofnąć scalenie. Teraz jednak nadszedł czas, aby połączyć 28ssię develop, ale komenda git seryjnej widzi oryginalnego seryjnej i radośnie informuje, że wszystko jest dobrze i gałęzie zostały już połączone. Co mam teraz zrobić? Utworzyć zatwierdzenie „Przywróć” Przywróć 28s -> rozwinąć „”? Nie wydaje się to dobrym sposobem na zrobienie tego, ale w tej chwili nie wyobrażam sobie żadnego innego.

Jak wygląda struktura drzewa:

Dane wyjściowe dziennika Git

Toms Mikoss
źródło
4
To jest GitX ( gitx.frim.nl ).
Toms Mikoss,

Odpowiedzi:

169

Musisz „cofnąć cofnięcie”. W zależności od Ciebie, w jaki sposób oryginał został przywrócony, może nie być tak łatwo, jak się wydaje. Zobacz oficjalny dokument na ten temat .

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

zezwolić:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

Ale czy to wszystko działa? Jasne, że tak. Możesz cofnąć scalenie, a z czysto technicznego punktu widzenia git zrobił to bardzo naturalnie i nie miał żadnych problemów.
Po prostu uznał to za zmianę z „stanu przed scaleniem” na „stan po scaleniu” i tyle.
Nic skomplikowanego, nic dziwnego, nic naprawdę niebezpiecznego. Git zrobi to, nawet o tym nie myśląc.

Z technicznego punktu widzenia nie ma nic złego w odwróceniu scalania, ale z punktu widzenia przepływu pracy jest to coś, czego na ogół powinieneś unikać .

Jeśli to możliwe, na przykład, jeśli okaże się, że problem został włączony do głównego drzewa, zamiast przywrócić seryjnej, spróbuj naprawdę ciężko :

  • podziel problem na część, którą scaliłeś, i po prostu napraw go,
  • lub spróbuj cofnąć indywidualne zatwierdzenie, które go spowodowało.

Tak, jest to bardziej skomplikowane, a nie, to nie zawsze będzie działać (czasem odpowiedź brzmi: „Oj, ja naprawdę nie powinno połączyły go, ponieważ nie był jeszcze gotowy, a ja naprawdę trzeba cofnąć wszystkie z łączyć"). Zatem naprawdę powinieneś cofnąć scalanie, ale jeśli chcesz ponownie wykonać scalenie, musisz to zrobić poprzez cofnięcie cofnięcia.

J-16 SDiZ
źródło
10
Dobry link (+1). Pozwoliłem sobie na skopiowanie części dokumentu w twojej odpowiedzi, aby umożliwić czytelnikom natychmiastowe zobaczenie odpowiednich opcji w tym przypadku. Jeśli się nie zgadzasz, możesz wrócić.
VonC
5
Właśnie natrafiliśmy na przypadek, w którym musieliśmy to zrobić i stwierdziliśmy, że zabawa nie kończy się tutaj. To był długo działający oddział, który został włączony, więc musieliśmy go nadal aktualizować. Moje podejście tutaj: tech.patientslikeme.com/2010/09/29/…
jdwyah
Śledziłem post na blogu @ jdwyah i było to wspaniałe (poważnie, było niesamowite, że to po prostu działało).
hellatan
2
@jdwyah, który wydaje się być zepsutym linkiem, ale brzmi jak ciekawa lektura. Oto lustro archive.org, ale brakuje w nim obrazów: web.archive.org/web/20111229193713/http://…
Alex KeySmith
15
Wpis na
jdwyah
53

Załóżmy, że masz taką historię

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

Gdzie A, B nie powiedzie się, a W - oznacza powrót do M

Więc zanim zacznę naprawiać znalezione problemy, wybieram W dla mojego oddziału

git cherry-pick -x W

Następnie cofam zatwierdzenie W w moim oddziale

git revert W 

Po tym, jak mogę kontynuować naprawianie.

Ostateczna historia może wyglądać następująco:

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

Kiedy wyślę PR, wyraźnie pokaże, że PR jest cofnięty, przywraca i dodaje kilka nowych zatwierdzeń.

Maksim Kotlyar
źródło
3
Wygląda na to, że może to być pomocne, ale jest tak rzadkie w szczegółach (jakie są C, D na ostatnim schemacie), że jest bardziej frustrujące niż przydatne
Isochronous
4
@ Isochronous C i D wydają się zatwierdzeniami, które naprawiają problemy wprowadzone przez A i B.
Thomas
@Thomas dokładnie
Maksim Kotlyar
Dobrze, że zaznaczyłeś użycie PR w tym przypadku, ponieważ może ono zapewnić ostateczną „kontrolę zdrowia” przed ponownym połączeniem z master.
Willem van Ketwich,
użyj, dlaczego ponownie uruchamiasz swój oddział z pierwotnego W? Tj. Pozwól, aby Twój temat był kontynuowany od W, z W`, po których następuje C i D? To usuwa pewne powielanie
Erik Carstensen
12

Aby cofnąć przywracanie bez nadmiernego zepsucia przepływu pracy:

  • Utwórz lokalną kopię śmieci dewelopera
  • Cofnij zatwierdzenie przywracania na lokalnej kopii programisty
  • Scal tę kopię z gałęzią funkcji i wypchnij gałąź funkcji na serwer git.

Twój oddział funkcji powinien być teraz w stanie normalnie zostać scalony, gdy będziesz na to gotowy. Jedynym minusem jest to, że będziesz mieć kilka dodatkowych zatwierdzeń scalania / przywracania w swojej historii.

Sam Dufel
źródło
Aby nie dopuścić do dalszych pomyłek, stworzyłem również „kosz” kopię mojej gałęzi funkcji i połączyłem w nią cofnięty rozwój.
jhhwilliams
Dziękuję Ci! To jedyna odpowiedź, która faktycznie wyjaśnia, jak to zrobić, zamiast mówić, że nie powinieneś tego robić. Naprawdę pomocna.
Emmy,
Dziękuję, to mi naprawdę pomogło. :)
Daniel Stracaboško
11

Aby cofnąć przywrócenie w GIT:

git revert <commit-hash-of-previous-revert>
Richard
źródło
1
Używam tego w mojej gałęzi pracy, aby przywrócić wycofanie, a następnie opracować nowy PR. Teraz git widzi wszystkie zmiany, które były w poprzednim PR, które zostały cofnięte. Dzięki.
Danstan
3

Zamiast tego git-revertmożesz użyć tego polecenia w develgałęzi, aby wyrzucić (cofnąć) niepoprawne zatwierdzenie scalania (zamiast po prostu cofnąć).

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

Spowoduje to również odpowiednie dostosowanie zawartości katalogu roboczego. Uważaj :

  • Zapisz zmiany w gałęzi developerskiej (ponieważ błędne scalenie), ponieważ one również zostaną usunięte przez git-reset. Wszystkie zatwierdzenia po tym, który podasz jako git resetargument, zniknie!
  • Nie rób tego również, jeśli zmiany zostały już pobrane z innych repozytoriów, ponieważ reset spowoduje przepisanie historii.

Zalecam git-resetuważne przestudiowanie strony podręcznika przed wypróbowaniem tego.

Teraz po zresetowaniu możesz ponownie zastosować zmiany, devela następnie zrobić to

git checkout devel
git merge 28s

Będzie to prawdziwe scalenie ze 28sw develniczym początkowego (który jest teraz wymazane z historii git za).

knweiss
źródło
8
Dla każdego, kto nie jest zaznajomiony z git i może chcieć postępować zgodnie z tymi instrukcjami: ostrożnie z łączeniem reset --hardi push origin. Pamiętaj też, że siła nacisku na pochodzenie może naprawdę zepsuć otwarte PR na GitHub.
funroll
Bardzo pomocny w naprawianiu niektórych problemów z scalaniem na prywatnym serwerze git. Dzięki!
mix3d
1
+1 za tę technikę. Potencjalnie destrukcyjny, ale może zaoszczędzić ci dużo bólu głowy (i zniekształconej historii), gdy zastosujesz go rozsądnie.
siliconrockstar
1

Właśnie znalazłem ten post w obliczu tego samego problemu. Uważam, że zbyt trudne jest resetowanie hards itp. W końcu skasuję coś, czego nie chcę i nie będę w stanie tego odzyskać.

Zamiast tego sprawdziłem zatwierdzenie, do którego chciałem, aby gałąź wróciła do np git checkout 123466t7632723. Następnie przekształcony w oddział git checkout my-new-branch. Następnie usunąłem gałąź, której już nie chciałem. Oczywiście zadziała to tylko wtedy, gdy będziesz w stanie wyrzucić gałąź, którą zawiodłeś.

Claire
źródło
1
git reflogOchroni cię na twardym resecie na kilka miesięcy w przypadku, gdy później odkryć, że trzeba utraconych zobowiązuje. Reflog jest ograniczony do twojego lokalnego repozytorium.
Todd
1

Sugeruję, abyś wykonał poniższe kroki, aby przywrócić przywrócenie, powiedz SHA1.

git checkout develop #go to develop branch
git pull             #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote

Teraz utwórz PR dla oddziału users/yourname/revertOfSHA1

Venkataraman R
źródło
1
  1. utwórz nowy oddział przy zatwierdzeniu przed pierwotnym scaleniem - nazwij go „develop-base”
  2. wykonaj interaktywną zmianę „rozwijania” na górze „rozwijania bazy” (nawet jeśli jest już na wierzchu). Podczas interaktywnej zmiany bazy będziesz mieć możliwość usunięcia zarówno zatwierdzenia scalania, jak i zatwierdzenia, które odwróciło scalanie, tj. Usuń oba zdarzenia z historii git

W tym momencie będziesz mieć czystą gałąź „rozwijania”, z którą możesz regularnie łączyć przeglądarkę funkcji.

Misza Mostow
źródło
Takie podejście stworzy problem, jeśli gałąź rozwoju zostanie udostępniona innym osobom.
PSR