Hoe kan ik een merge-commit die al naar de remote branch is gepusht terugzetten?

git revert <commit_hash>alleen zal niet werken. -mmoet worden opgegeven, en ik ben er behoorlijk in de war over.

Heeft iemand dit eerder meegemaakt?


Antwoord 1, autoriteit 100%

De optie -mspecificeert het oudernummer. Dit komt omdat een merge-commit meer dan één ouder heeft, en Git weet niet automatisch welke ouder de hoofdregel was, en welke ouder de branch was die je wilt samenvoegen.

Als je een merge-commit in de uitvoer van git logbekijkt, zie je de ouders op de regel die begint met 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

In deze situatie zal git revert 8f937c6 -m 1je de tree geven zoals deze was in 8989ee0, en git revert -m 2herstelt de structuur zoals deze was in 7c6b236.

Om de ouder-ID’s beter te begrijpen, kunt u het volgende uitvoeren:

git log 8989ee0 

en

git log 7c6b236

Antwoord 2, autoriteit 31%

Hier is een compleet voorbeeld in de hoop dat het iemand helpt:

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

Waar <commit-hash>de commit-hash is van de samenvoeging die je wilt terugdraaien, en zoals vermeld in de uitleg van dit antwoord, -m 1geeft aan dat u wilt terugkeren naar de stamboom van de eerste ouder voorafgaand aan de samenvoeging.

De regel git revert ...legt in wezen uw wijzigingen vast, terwijl de tweede regel uw wijzigingen openbaar maakt door ze naar de externe branch te pushen.


Antwoord 3, autoriteit 13%

Ben heeft je verteld hoe je een merge-commit kunt terugdraaien, maar het is erg belangrijkdat je je realiseert dat je dit doet

“…verklaart dat je de boomveranderingen die door de samenvoeging zijn aangebracht, nooit zult willen hebben. Als resultaat zullen latere samenvoegingen alleen boomveranderingen opleveren die zijn geïntroduceerd door vastleggingen die geen voorouders zijn van de eerder teruggedraaide samenvoeging. Dit kan wel of niet zijn wat je wilt.(git-merge man-pagina).

Een artikel/mailing list messagegelinkt vanaf de man-pagina geeft details over de mechanismen en overwegingen die erbij betrokken zijn. Zorg er wel voor dat je begrijpt dat als je de merge-commit terugdraait, je niet zomaar de branch later opnieuw kunt mergen en verwachten dat dezelfde wijzigingen terugkomen.


Antwoord 4, autoriteit 6%

Je zou deze stappen kunnen volgen om de incorrecte commit(s) terug te zetten of om je remote branch terug te zetten naar de juiste HEAD/state.

  1. check de remote branch naar de lokale repo af.
    git checkout your_branch_name
  2. kopieer de commit hash (d.w.z. id van de commit direct voor de verkeerde commit) van git log
    git log -n5

zou zoiets als dit moeten tonen:

commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 “Vertakking samenvoegen
‘wrong-commit’ in ‘your_branch_name'”
commit
f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 “dit is een verkeerde commit”
commit 3779ab50e72908da92d2cfcd72256d7a09f446ba “dit is de juiste
commit”

  1. reset de branch naar de commit-hash die in de vorige stap is gekopieerd
    git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
  2. voer de git statusuit om alle wijzigingen te tonen die deel uitmaakten van de verkeerde commit.
  3. voer gewoon git reset --harduit om al die wijzigingen ongedaan te maken.
  4. Duw je lokale branch geforceerd naar remote en merk op dat je commit-geschiedenis schoon is zoals het was voordat het vervuild raakte.
    git push -f origin your_branch_name

Opmerking: Pas deze oplossing alleen toe voor uw eigen filiaal, niet voor een gedeelde filiaal.


Antwoord 5, autoriteit 5%

git revert -m 1 <merge-commit>

Antwoord 6, autoriteit 2%

Om het logboek schoon te houden omdat er niets is gebeurd (met enkele nadelen met deze aanpak (vanwege push -f)):

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

‘commit-hash-before-merge’ komt uit het logboek (git log) na het samenvoegen.


Antwoord 7

Soms is de meest effectieve manier om terug te draaien, een stap terug te doen en te vervangen.

git log

Gebruik de 2e commit-hash (volledige hash, degene waarnaar je wilt terugkeren, vóór de vermelde fout) en vertak vervolgens vanaf daar.

git checkout -b newbranch <HASH>

Verwijder vervolgens de oude vertakking, kopieer de nieuwe vertakking op zijn plaats en start vanaf daar opnieuw.

git branch -D oldbranch
git checkout -b oldbranch newbranch

Als het is uitgezonden, verwijder dan de oude vertakking uit alle repositories, duw de opnieuw gemaakte vertakking naar de meest centrale en trek hem terug naar alle.


Antwoord 8

Alle antwoorden hebben de meeste dingen al behandeld, maar ik zal mijn 5 cent toevoegen.
In het kort is het terugdraaien van een merge-commit vrij eenvoudig:

git revert -m 1 <commit-hash>

Als je toestemming hebt, kun je het rechtstreeks naar de “master” -branch pushen, anders push je het gewoon naar je “revert” -branch en maak je een pull-verzoek.

Misschien vindt u hier meer nuttige informatie over dit onderwerp: https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html


Antwoord 9

Als je een Mergecommit wilt terugdraaien, moet je het volgende doen.

  1. Controleer eerst het git logom de id van je merge commit te vinden. Je zult ook meerdere ouder-ID’s vinden die zijn gekoppeld aan de samenvoeging (zie onderstaande afbeelding).

voer hier de afbeeldingsbeschrijving in

Noteer de merge commit id die in geel wordt weergegeven.
De ouder-ID’s zijn degene die in de volgende regel zijn geschreven als Merge: parent1 parent2. Nu…

Kort verhaal:

  1. Schakel over naar de vertakking waarop de samenvoeging is gemaakt. Doe dan gewoon de git revert <merge commit id> -m 1die een vi-console opent voor het invoeren van een commit-bericht. Schrijven, opslaan, afsluiten, klaar!

Lang verhaal:

  1. Schakel over naar de vertakking waarop de samenvoeging is gemaakt. In mijn geval is dit de vertakking testen ik probeer de vertakking feature/analytics-v3eruit te verwijderen.

  2. git revertis het commando dat elke commit terugdraait. Maar er is een vervelende truc bij het terugzetten van een Mergecommit. U moet de vlag -minvoeren, anders mislukt het. Vanaf hier moet je beslissen of je je branch wilt terugzetten en het er precies zo uit wilt laten zien als op parent1of parent2via:

git revert <merge commit id> -m 1(keert terug naar parent2)

git revert <merge commit id> -m 2(keert terug naar parent1)

Je kunt deze ouders loggen om erachter te komen welke kant je op wilt en dat is de oorzaak van alle verwarring.


Antwoord 10

Ik vond een goede uitleg voor How To Revert The Mergevan deze linken ik kopieer en plak de onderstaande uitleg en het zou nuttig zijn voor het geval de onderstaande link niet werkt.

Een foutieve samenvoeging ongedaan maken
Alan([email protected]) zei:

Ik heb een master-branch. We hebben daar een tak van die sommigen
ontwikkelaars werken aan. Ze beweren dat het klaar is. We voegen het samen
in de master-branch. Het breekt iets, dus we keren de samenvoeging terug.
Ze brengen wijzigingen aan in de code. ze komen op een punt waarop ze zeggen:
het is goed en we fuseren weer.
Bij onderzoek zien we dat codewijzigingen die vóór het terugzetten zijn gemaakt, zijn
niet in de master branch, maar codewijzigingen daarna zijn in de master
tak.
en vroeg om hulp bij het herstellen van deze situatie.

De geschiedenis onmiddellijk na het “terugzetten van de samenvoeging” zou er als volgt uitzien:

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

waar A en B zich aan de zijlijn bevinden die niet zo goed was, M is de samenvoeging die deze voortijdige veranderingen in de hoofdlijn brengt, x zijn veranderingen die niets te maken hebben met wat de zijtak deed en al maakte op de hoofdlijn, en W is de “terugkeer van de samenvoeging M” (ziet W er M niet ondersteboven uit?). IOW, “diff W^..W” is vergelijkbaar met “diff -R M^..M”.

Zo’n “terugzetten” van een samenvoeging kan gemaakt worden met:

$ git revert -m 1 M
Nadat de ontwikkelaars van de zijtak hun fouten hebben hersteld, kan de geschiedenis er als volgt uitzien:

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

waar C en D zijn om te repareren wat kapot was in A en B, en je hebt misschien al wat andere wijzigingen op de hoofdlijn na W.

Als je de bijgewerkte zijtak samenvoegt (met D aan de punt), zal geen van de wijzigingen die in A of B zijn gemaakt in het resultaat zijn, omdat ze zijn teruggedraaid door W. Dat is wat Alan zag.

Linus legt de situatie uit:

Het terugzetten van een normale commit maakt gewoon effectief wat die commit ongedaan maakt
deed, en is vrij eenvoudig. Maar het terugzetten van een merge-commit ook
maakt de gegevensdie de commit heeft gewijzigd ongedaan, maar doet dit absoluut
niets aan de effecten op de geschiedenisdie de samenvoeging had.
Dus de samenvoeging zal nog steeds bestaan, en het zal nog steeds worden gezien als samenvoegen
de twee takken samen, en toekomstige samenvoegingen zullen die samenvoeging zien als
de laatste gedeelde status – en het terugzetten dat de samenvoeging terugdraaide bracht
in heeft daar helemaal geen invloed op.
Dus een “revert” maakt de gegevenswijzigingen ongedaan, maar het is in hoge mate nieteen
“ongedaan maken” in de zin dat het de effecten van een commit op
de archiefgeschiedenis.
Dus als je denkt aan “terugzetten” als “ongedaan maken”, dan ga je altijd
mis dit deel van terugkeert. Ja, het maakt de gegevens ongedaan, maar nee, dat doet het niet
geschiedenis ongedaan maken.
In zo’n situatie zou je eerst de vorige terugzetting willen terugdraaien, waardoor de geschiedenis er als volgt uit zou zien:

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

waarbij Y de revert van W is. Zo’n “revert of the revert” kan met:

$ git revert W
Deze geschiedenis zou (mogelijke conflicten negeren tussen wat W en W..Y hebben veranderd) gelijk staan ​​aan het helemaal niet hebben van W of Y in de geschiedenis:

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

en het opnieuw samenvoegen van de zijtak zal geen conflict hebben dat voortvloeit uit een eerdere terugzetting en teruggave van de terugzetting.

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

Natuurlijk kunnen de wijzigingen in C en D nog steeds in strijd zijn met wat door een van de x is gedaan, maar dat is gewoon een normaal samenvoegconflict.


Antwoord 11

Dit is een heel oude thread, maar ik mis een andere naar mijn mening handige oplossing:

Ik zet een samenvoeging nooit terug. Ik maak gewoon een andere tak van de revisie waar alles in orde was en kies dan alles wat moet worden geplukt uit de oude tak die ertussenin is toegevoegd.

Dus, als de GIT-geschiedenis zo is:

  • d
  • c
  • b <<< de samenvoeging
  • een

Ik maak een nieuwe tak van a, cherry pick c en d en dan is de nieuwe tak vrij van b. Ik kan ooit besluiten om de merge van “b” in mijn nieuwe branch opnieuw te doen. De oude branch wordt verouderd en wordt verwijderd als “b” niet meer nodig is of nog in een andere (feature/hotfix) branch.

Het enige probleem is nu een van de moeilijkste dingen in de informatica: hoe noem je de nieuwe tak? 😉

Ok, als je gefaald hebt in het bijzonder. in devel maak je newdevel aan zoals hierboven vermeld, verwijder je oude devel en hernoem je newdevel naar devel.
Missie volbracht. U kunt de wijzigingen nu opnieuw samenvoegen wanneer u maar wilt. Het is als nooit tevoren samengevoegd….


Antwoord 12

Ik ontdekte dat het maken van een omgekeerde patch tussen twee bekende eindpunten en het toepassen van die patch zou werken. Dit veronderstelt dat je snapshots (tags) hebt gemaakt van je master branch of zelfs een back-up van je master branch, bijvoorbeeld master_bk_01012017.

Stel dat de codebranch die je hebt samengevoegd tot master mycodebranch was.

  1. Kassa-master.
  2. Maak een volledige binaire reverse patch tussen master en je back-up.
    git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. Controleer uw pleister
    git apply --check myrevert.patch
  4. Pas patch toe met afmelding
    git am --signoff < myrevert.patch
  5. Als u deze code opnieuw moet invoeren zodra deze is gerepareerd, moet u de teruggekeerde master vertakken en de fix-branch uitchecken
    git branch mycodebranch_fix
    git checkout mycodebranch_fix
  6. Hier moet je de SHA-sleutel voor het terugzetten vinden en het terugzetten terugzetten
    git revert [SHA]
  7. Nu kun je je mycodebranch_fix gebruiken om de problemen op te lossen, vast te leggen en opnieuw samen te voegen in master zodra je klaar bent.

Antwoord 13

Het correct gemarkeerde antwoord werkte voor mij, maar ik moest wat tijd besteden om te bepalen wat er aan de hand was. Dus besloot ik een antwoord toe te voegen met eenvoudige, duidelijke stappen voor gevallen zoals het mijne..

Laten we zeggen dat we branches A en B hebben.. Je hebt branch A in branch B samengevoegd en branch B naar zichzelf gepusht, dus nu maakt de merge er deel van uit.. Maar je wilt terug naar de laatste commit vóór de samenvoeging.. Wat doe je?

  1. Ga naar je git-hoofdmap (meestal de projectmap) en gebruik git log
  2. Je zult de geschiedenis van recente commits zien – de commits hebben commit/author/date eigenschappen terwijl de merges ook een merge eigenschap hebben – dus je ziet ze als volgt:

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

  3. Gebruik git log <parentHashA>en git log <parentHashB>– je zult de commit-geschiedenissen van die bovenliggende branches zien – de eerste commits in de lijst zijn de nieuwste

  4. Neem de <commitHash>van de commit die je wilt, ga naar je git-hoofdmap en gebruik git checkout -b <newBranchName> <commitHash>– dat zal een nieuwe branch aanmaken vanaf die laatste commit die je hebt gekozen voor de merge.. Voila, klaar!

Antwoord 14

git doc over git revert -m geef een link om dit precies uit te leggen:
https://github.com/ git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt


Antwoord 15

-m1 is de laatste ouder van de huidige vertakking die wordt gerepareerd, -m 2 is de oorspronkelijke ouder van de vertakking die hierin is samengevoegd.

Tortoise Git kan hier ook helpen als de opdrachtregel verwarrend is.


Antwoord 16

Een heel eenvoudig antwoord als u de wijziging die u zojuist heeft doorgevoerd wilt terugdraaien:

commit 446sjb1uznnmaownlaybiosqwbs278q87
Merge: 123jshc 90asaf
git revert -m 2 446sjb1uznnmaownlaybiosqwbs278q87 //does the work

Antwoord 17

Ik heb dit probleem ook ondervonden bij een PR die is samengevoegd met de master-branch van een GitHub-repo.

Omdat ik alleen wat gewijzigde bestanden wilde wijzigen, maar niet alle veranderingen die de PR met zich meebracht, moest ik de amendmerge commitmet git commit --am.

Stappen:

  1. Ga naar de branch die je wilt wijzigen / terugzetten van enkele gewijzigde bestanden
  2. Voer de gewenste wijzigingen uit volgens gewijzigde bestanden
  3. voer git add *of git add <file>
  4. uit

  5. voer git commit --amuit en valideer
  6. voer git push -f
  7. uit

Waarom het interessant is:

  • Het houdt de auteurscommitment van de PR ongewijzigd
  • Het breekt de git-boom niet
  • Je wordt gemarkeerd als committer (samenvoegen auteur blijft ongewijzigd)
  • Git handelt alsof je conflicten hebt opgelost, het zal de code in gewijzigde bestanden verwijderen/wijzigen alsof je GitHub handmatig vertelt om het niet samen te voegen zoals het is

Antwoord 18

Als je een merge-commit in de uitvoer van git logbekijkt, zie je de ouders op de regel die begint met 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

In deze situatie zal git revert 8f937c6 -m 1je de tree geven zoals deze was in 8989ee0, en git revert -m 2herstelt de structuur zoals deze was in 7c6b236.

Om de ouder-ID’s beter te begrijpen, kunt u het volgende uitvoeren:

git log 8989ee0 

en

git log 7c6b236

Neem een ​​back-uptak

git checkout -b mybackup-brach
git reset --hard 8989ee0 
git push origin -u mybackup-branch

Dus nu heb je de wijzigingen voor de samenvoeging. Als alles in orde is, check je uit in de vorige branch en reset je met een back-up branch

git reset --hard origin/mybakcup-branhc

Antwoord 19

Zoals Ryan al zei, kan git reverthet samenvoegen later bemoeilijken, dus git revertis misschien niet wat je wilt. Ik vond dat het gebruik van de opdracht git reset --hard <commit-hash-prior-to-merge>hier nuttiger was.

Als je eenmaal het harde reset gedeelte hebt gedaan, kun je push forceren naar de remote branch, d.w.z. git push -f <remote-name> <remote-branch-name>, waarbij <remote-name>vaak originwordt genoemd. Vanaf dat moment kun je opnieuw samenvoegen als je wilt.

Other episodes