Jak przywrócić commit scalający, który został już wypchnięty do zdalnej gałęzi?

git revert <commit_hash> sama nie zadziała. -m musi być sprecyzowany, i jestem trochę zdezorientowany.

Ktoś już tego doświadczył?
 1140
git
Author: CodeNotFound, 2011-08-17

18 answers

Opcja -m określa numer rodzica . Dzieje się tak dlatego, że commit scalający ma więcej niż jednego rodzica, a Git nie wie automatycznie, który rodzic był główną linią, a który rodzicem był gałęzią, którą chcesz odłączyć.

Kiedy zobaczysz commit scalający w wyniku git log, zobaczysz jego rodziców w linii zaczynającej 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 1 zdobędzie drzewo tak, jak było w 8989ee0, a git revert -m 2 przywróci drzewo jak to było w 7c6b236.

Aby lepiej zrozumieć identyfikatory rodzica, możesz uruchomić:

git log 8989ee0 

I

git log 7c6b236
 1390
Author: Ben James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 13:21:03

Oto kompletny przykład w nadziei, że komuś pomoże:

git revert -m 1 <commit-hash> 
git push -u origin master

Gdzie <commit-hash> jest skrótem zatwierdzania połączenia, który chcesz przywrócić, i jak podano w wyjaśnieniu tej odpowiedzi, -m 1 oznacza, że chcesz przywrócić drzewo pierwszego rodzica przed połączeniem.

Linia git revert ... zasadniczo zatwierdza twoje zmiany, podczas gdy druga linia upublicznia je, popychając je do zdalnej gałęzi.

 429
Author: Saheed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 22:51:55

Ben powiedział Ci, jak przywrócić commit scalający, ale to jest bardzo ważne zdajesz sobie sprawę, że robiąc to

"...oświadcza, że nigdy nie będziesz chciał zmian w drzewie wprowadzonych przez połączenie. W rezultacie późniejsze scalenia wprowadzą tylko zmiany w drzewie wprowadzone przez commity, które nie są przodkami wcześniej cofniętego scalenia. To może być to, czego chcesz." (git-merge man page) .

An artykuł/wiadomość na liście dyskusyjnej linked from the man page details the mechanisms and considerations that are involved. Upewnij się tylko, że rozumiesz, że jeśli przywrócisz commit scalający, nie możesz po prostu połączyć gałęzi ponownie później i oczekiwać, że te same zmiany powrócą.

 190
Author: Ryan Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-19 15:26:30

Możesz wykonać następujące kroki, aby przywrócić niepoprawne zmiany lub zresetować zdalną gałąź z powrotem do poprawnej głowy / stanu.

  1. sprawdź zdalny oddział do lokalnego repo.
    git checkout development
  2. Skopiuj hash zatwierdzenia (tzn. id zatwierdzenia bezpośrednio przed błędnym zatwierdzeniem) z git log git log -n5

    Wyjście:

    Zatwierdź 7cd42475d6f95f5896b6f02e902efab0b70e8038 "Połącz gałąź' wrong-commit ' w 'development '"
    commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "this is a wrong commit"
    commit 3779ab50e72908da92d2cfcd72256d7a09f446ba "to jest poprawny commit"

  3. Zresetuj gałąź do skrótu zatwierdzania skopiowanego w poprzednim kroku
    git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. Uruchom git status, aby pokazać wszystkie zmiany, które były częścią błędnego commita.
  5. po prostu uruchom git reset --hard, aby przywrócić wszystkie te zmiany.
  6. force-wypchnij lokalną gałąź do zdalnego i zauważ, że Twoja historia zmian jest czysta tak jak było, zanim został zanieczyszczony.
    git push -f origin development
 83
Author: ssasi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 11:41:28
git revert -m 1 <merge-commit>
 67
Author: Neeraj Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 14:03:35

Aby dziennik był czysty, ponieważ nic się nie stało (z pewnymi minusami z tym podejściem (z powodu push-f)):

git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>

'commit-hash-before-merge' pochodzi z dziennika (git log) po połączeniu.

 33
Author: nvd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 08:43:43

Czasami najskuteczniejszym sposobem wycofania jest cofnięcie się i wymiana.

git log

Użyj 2nd commit hash (pełny hash, do którego chcesz wrócić, przed błędem podanym na liście), a następnie zmień nazwę.

git checkout -b newbranch <HASH>

Następnie usuń starą gałąź, skopiuj nową gałąź na jej miejsce i uruchom ponownie stamtąd.

git branch -D oldbranch
git checkout -b oldbranch newbranch

Jeśli została nadana, usuń starą gałąź ze wszystkich repozytoriów, przesuń gałąź redone do najbardziej centralnej i pociągnij wszystko wróciło do normy.

 19
Author: ppostma1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 01:29:41

Wszystkie odpowiedzi już obejmowały większość rzeczy, ale dodam moje 5 centów. W skrócie przywrócenie commita scalającego jest dość proste:

git revert -m 1 <commit-hash>

Jeśli posiadasz uprawnienia, możesz przesunąć je bezpośrednio do gałęzi "master", w przeciwnym razie po prostu przesunąć je do gałęzi "revert" i utworzyć pull request.

Więcej przydatnych informacji na ten temat znajdziesz tutaj: https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html

 12
Author: xproph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-27 15:16:27

Jeśli chcesz przywrócić merge commit, oto co musisz zrobić.

  1. najpierw sprawdź git log, aby znaleźć identyfikator commita scalającego. Znajdziesz również wiele identyfikatorów nadrzędnych powiązanych z scaleniem(patrz obrazek poniżej).

Tutaj wpisz opis obrazka

Zanotuj identyfikator commitu scalającego pokazany na Żółto. ID rodzica to identyfikatory zapisane w następnej linii jako Merge: parent1 parent2. Teraz...

Opowiadanie:

  1. Przełącz na gałąź, na której dokonano połączenia. Wtedy Po prostu wykonaj git revert <merge commit id> -m 1, która otworzy konsolę vi do wpisania komunikatu commit. Napisz, Zapisz, wyjdź, gotowe!

Długa historia:

  1. Przełącz na gałąź, na której dokonano połączenia. W moim przypadku jest to gałąź test i staram się usunąć z niej gałąź feature/analytics-v3.

  2. git revert to polecenie, które odwraca każdy commit. Ale istnieje paskudna sztuczka podczas przywracania merge commit. Musisz wprowadzić flagę -m w przeciwnym razie to się nie powiedzie. Od teraz ty musisz zdecydować, czy chcesz przywrócić swoją gałąź i sprawić, aby wyglądała dokładnie tak, jak była na parent1 lub parent2 poprzez:

git revert <merge commit id> -m 1 (Powrót do parent2)

git revert <merge commit id> -m 2 (powrót do parent1)

Możesz zalogować tych rodziców, aby dowiedzieć się, w którą stronę chcesz iść i to jest źródło całego zamieszania.

 6
Author: saran3h,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-09 05:03:50

Znalazłem dobre wyjaśnienie Jak przywrócić Merge z tego linku i skopiowałem wklejone Wyjaśnienie poniżej i byłoby pomocne na wszelki wypadek, gdyby poniższy link nie działał.

Jak przywrócić wadliwe scalanie Alan([email protected]) said:

Mam gałąź główną. Mamy gałąź z tego, że niektóre deweloperzy pracują nad. Twierdzą, że jest gotowa. Łączymy to do gałęzi głównej. To coś łamie więc wracamy do / align = "left" / Wprowadzają zmiany w kodzie. docierają do punktu, w którym mówią jest ok i znowu się łączymy. Po zbadaniu okaże się, że zmiany kodu dokonane przed przywróceniem są Nie w gałęzi master, ale zmiany kodu po są w master branch. i poprosił o pomoc w wyzdrowieniu z tej sytuacji.

Historia bezpośrednio po "przywróceniu połączenia" wyglądałaby tak:

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

Gdzie A i B są po stronie Rozwoju, który nie był tak dobry, M jest połączeniem, które wprowadza te przedwczesne zmiany do linii głównej, x są zmianami niezwiązanymi z tym, co boczna gałąź zrobiła i już zrobiła na linii głównej, a W jest "odwróceniem merge M" (czy W nie wygląda m do góry nogami?). IOW, " diff w^..W "jest podobny do" diff-R M^..M".

Taki "rewert" połączenia można wykonać za pomocą:

$ git revert-m 1 m Po tym, jak twórcy gałęzi pobocznej naprawią swoje błędy, historia może wyglądać tak: {]}

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

Gdzie C i D mają naprawić to, co było w przeciwieństwie do poprzednich wersji, nie jest to możliwe.]}

Jeśli połączysz zaktualizowaną gałąź boczną (z D na jej końcu), żadna ze zmian wprowadzonych w A lub B nie będzie w wyniku, ponieważ zostały one przywrócone przez W. To widział Alan.

Linus wyjaśnia sytuację:

Odwrócenie zwykłego commita skutecznie anuluje to, co ten commit tak, i jest to dość proste. Ale przywrócenie commit merge również wycofuje dane, które commit się zmienił, ale robi to absolutnie nic do wpływu na historię że połączenie miało. Więc połączenie nadal będzie istnieć i nadal będzie postrzegane jako połączenie dwie gałęzie razem, a przyszłe połączenia zobaczą, że łączą się jako ostatni wspólny stan - i odwrócenie, które cofnęło połączenie, przyniosło nie wpłynie to na to w ogóle. Więc "Odwróć" cofnie zmiany danych, ale to bardzo nie an "undo" w tym sensie, że nie cofnie efektów commita na na historia repozytorium. Więc jeśli myślisz o "Przywróć" jako "Cofnij", to zawsze będziesz miss tej części reverts. Tak, wycofuje dane, ale Nie, Nie Cofnij historię. W takiej sytuacji chciałbyś najpierw przywrócić poprzedni rewert, co sprawiłoby, że historia wyglądałaby tak:

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

Gdzie Y jest odwróceniem W. takie "odwrócenie odwrócenia" można wykonać za pomocą:

$ git revert w Tej historii (pomijając ewentualne konflikty między tym, co W.Y zmiana) jest równoznaczna z brakiem W lub Y w ogóle w historii:

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

I ponowne połączenie gałęzi bocznej nie spowoduje konfliktu wynikającego z wcześniejszego rewert i rewert rewert.

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

Oczywiście zmiany wprowadzone w C i D nadal mogą być sprzeczne z tym, co zostało zrobione przez którekolwiek z X, ale to jest zwykły konflikt scalania.

 4
Author: MK446,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-10 19:49:30

To bardzo stary wątek, ale brakuje mi innego moim zdaniem wygodnego rozwiązania:

Nigdy nie cofam połączenia. Po prostu utworzyć kolejną gałąź z rewizji, gdzie wszystko było ok, a następnie cherry wybrać wszystko, co trzeba wybrać ze starej gałęzi, która została dodana pomiędzy.

Więc, jeśli historia Gita jest taka:

  • d
  • c
  • b
  • a
  • ...

Tworzę nową gałąź z a, cherry pick c I d i wtedy nowa gałąź jest wolna od B. mogę kiedykolwiek zdecydować się na połączenie " b " w moim nowym oddziale ponownie. Stara gałąź staje się przestarzała i zostanie usunięta, jeśli "b" nie jest już konieczne lub nadal w innej gałęzi (feature/hotfix).

Jedynym problemem jest teraz jedna z najtrudniejszych rzeczy w informatyce: jak nazwać nową gałąź? ;)

Ok, jeśli zawiodłeś esp. w devel tworzysz newdevel jak wspomniano powyżej, usuwasz Stary devel i zmieniasz nazwę newdevel na devel. Misja / align = "left" / Możesz teraz ponownie scalić zmiany, kiedy chcesz. Jest jak nigdy wcześniej....

 2
Author: miwoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-23 13:02:47

Stwierdziłem, że utworzenie odwrotnej łatki między dwoma znanymi punktami końcowymi i zastosowanie tej łatki zadziała. Zakłada to, że utworzyłeś migawki (tagi) z gałęzi master lub nawet kopię zapasową gałęzi master powiedzmy master_bk_01012017.

Powiedzmy, że gałąź kodu, którą połączyłeś z master, to mycodebranch.

  1. Checkout master.
  2. Utwórz pełną binarną łatkę odwrotną między master a backupem. git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. Sprawdź plaster git apply --check myrevert.patch
  4. Zastosuj łatka z podpisem git am --signoff < myrevert.patch
  5. Jeśli będziesz musiał wprowadzić ten kod ponownie po jego naprawieniu, będziesz musiał odgałęziać się od cofniętego wzorca i kasować gałąź fix git branch mycodebranch_fix git checkout mycodebranch_fix
  6. tutaj musisz znaleźć klucz SHA dla odwrócenia i odwrócić odwrócenie git revert [SHA]
  7. Teraz możesz użyć mycodebranch_fix, aby naprawić problemy, zatwierdzić i ponownie połączyć się z master po zakończeniu.
 1
Author: alexplain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 15:57:45

Poprawnie oznaczona odpowiedź zadziałała dla mnie, ale musiałem poświęcić trochę czasu, aby ustalić, co się dzieje.. Postanowiłem więc dodać odpowiedź z prostymi prostymi krokami dla takich przypadków jak moja..

Powiedzmy, że mamy gałęzie A I B.. Połączyłeś gałąź A w gałąź B i popchnąłeś gałąź B do siebie, więc teraz połączenie jest jego częścią.. Ale chcesz wrócić do ostatniego commita przed połączeniem.. Czym się zajmujesz?
  1. przejdź do głównego folderu git (folder projektu zazwyczaj) i używać git log
  2. Zobaczysz historię ostatnich commitów-commity mają właściwości commit / author/date, podczas gdy merge mają również właściwość merge - więc zobaczysz je w następujący sposób:

    commit: <commitHash> Merge: <parentHashA> <parentHashB> Author: <author> Date: <date>

  3. Użyj git log <parentHashA> i git log <parentHashB> - zobaczysz historię zatwierdzeń tych gałęzi nadrzędnych - pierwsze commity na liście to najnowsze

  4. weź <commitHash> commit, który chcesz, przejdź do głównego folderu git i użyj git checkout -b <newBranchName> <commitHash> - który utworzy nowa gałąź zaczyna się od ostatniego commita, który wybrałeś przed połączeniem.. Gotowe!
 1
Author: Божидар Йовчев,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-02 10:58:47

Git doc o git revert-m podaj link dokładnie wyjaśnij to: https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt

 1
Author: Junyong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-14 07:39:50

- M1 jest ostatnim rodzicem bieżącej gałęzi, która jest naprawiana ,- m 2 jest oryginalnym rodzicem gałęzi, która została scalona.

Tortoise Git może również pomóc tutaj, jeśli linia komend jest myląca.

 1
Author: Vinay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-28 15:07:12

Miałem również do czynienia z tym problemem na PR, który został połączony z gałęzią master repo GitHub.

Ponieważ chciałem tylko zmodyfikować niektóre zmodyfikowane pliki, ale nie całe zmiany, które przyniósł PR, musiałem amend merge commit z git commit --am.

Kroki:

  1. przejdź do gałęzi, w której chcesz zmienić / przywrócić zmodyfikowane pliki
  2. czy zmiany, które chcesz według zmodyfikowanych plików
  3. run git add * or git add <file>
  4. run git commit --am and validate
  5. run git push -f

Dlaczego jest to ciekawe:

  • zachowuje autorski commit PR bez zmian
  • to nie łamie drzewa Gita
  • zostaniesz oznaczony jako committer (merge commit author pozostanie bez zmian)
  • Git zachowuje się tak, jakbyś rozwiązał konflikty, usunie / zmieni kod w zmodyfikowanych plikach tak, jakbyś ręcznie powiedział Githubowi, aby nie łączył go jako-is
 0
Author: Maxime Lafarie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-07 10:41:50

Bardzo prosta odpowiedź, jeśli chcesz przywrócić zmianę, którą przed chwilą wprowadziłeś:

commit 446sjb1uznnmaownlaybiosqwbs278q87
Merge: 123jshc 90asaf


git revert -m 2 446sjb1uznnmaownlaybiosqwbs278q87 //does the work
 0
Author: arqam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-19 14:28:00

Jak wspomniał Ryan, git revert może utrudnić połączenie, więc git revert może nie być tym, czego chcesz. Okazało się, że użycie polecenia git reset --hard <commit-hash-prior-to-merge> jest tutaj bardziej przydatne.

Po wykonaniu części hard reset, możesz wymusić przesunięcie do zdalnej gałęzi, np. git push -f <remote-name> <remote-branch-name>, Gdzie <remote-name> jest często nazywane origin. Od tego momentu możesz ponownie połączyć się, jeśli chcesz.

 -2
Author: Harry Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 15:18:15