Maak een Git merge ongedaan die nog niet is gepusht

Binnen mijn master-branch deed ik een git merge some-other-branchlokaal, maar heb de wijzigingen nooit naar de origin master gepusht. Het was niet mijn bedoeling om samen te voegen, dus ik wil het ongedaan maken. Toen ik een git statusdeed na mijn samenvoeging, kreeg ik dit bericht:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Gebaseerd op enkele instructies die ik heb gevonden , ik heb geprobeerd te rennen

git revert HEAD -m 1

maar nu krijg ik dit bericht met git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

Ik wil niet dat mijn branch een aantal commits voorloopt. Hoe kom ik op dat punt terug?


Antwoord 1, autoriteit 100%

Met git reflogcontroleer welke commit er één is voorafgaand aan de samenvoeging (git reflogzal een betere optie zijn dan git log). Dan kun je het resetten met:

git reset --hard commit_sha

Er is ook een andere manier:

git reset --hard HEAD~1

Je krijgt 1 commit terug.

Houd er rekening mee dat alle gewijzigde en niet-vastgelegde/niet opgeslagen bestanden worden teruggezet naar hun ongewijzigde staat. Om ze te bewaren, bergt u wijzigingen op of bekijkt u de optie --mergehieronder.


Zoals @Velmont hieronder in zijn antwoord suggereerde, in dit directe geval met:

git reset --hard ORIG_HEAD

kan betere resultaten opleveren, omdat uw wijzigingen behouden blijven. ORIG_HEADverwijst naar een commit direct voordat de merge heeft plaatsgevonden, dus je hoeft er niet zelf naar te zoeken.


Een andere tip is om de schakelaar --mergete gebruiken in plaats van --hard, omdat het bestanden niet onnodig opnieuw instelt:

git reset --merge ORIG_HEAD

–merge

Herstelt de index en werkt de bestanden in de werkboom bij die verschillen tussen <commit> en HEAD, maar behoudt de verschillen tussen de index en de werkboom (d.w.z. die wijzigingen hebben die niet zijn toegevoegd).


Antwoord 2, autoriteit 31%

Ervan uitgaande dat uw lokale meester niet voor was op origin/master, zou u dit moeten kunnen doen

git reset --hard origin/master

Dan zou je lokale masterbranch er identiek uit moeten zien als origin/master.


Antwoord 3, autoriteit 24%

Zie hoofdstuk 4 in het Git-boeken het originele bericht van Linus Torvalds.

Een samenvoeging ongedaan maken die al is gepusht:

git revert -m 1 commit_hash

Zorg ervoor dat je het terugzet terugzet als je de branch opnieuw commit, zoals Linus zei.


Antwoord 4, autoriteit 21%

Het is vreemd dat het eenvoudigste commando ontbrak. De meeste antwoorden werken, maar als u het samenvoegen ongedaan maakt, dit is de gemakkelijke en veilige manier:

git reset --merge ORIG_HEAD

De ref ORIG_HEADzal verwijzen naar de originele commit van voor de merge.

(De --mergeoptie heeft niets te maken met het samenvoegen. Het is net als git reset --hard ORIG_HEAD, maar veiliger omdat het niet uncommitted raakt wijzigingen.)


5, Autoriteit 3%

U moet instellen op de vorige commit. Dit zou moeten werken:

git reset --hard HEAD^

of zelfs HEAD^^Om die keren terug te keren. U kunt altijd een volledige SHA-referentie geven als u niet zeker weet hoeveel stappen terug u moet nemen.

In het geval dat u problemen ondervindt en uw Master Branch geen lokale wijzigingen had, kunt u resetten naar origin/master.


6, Autoriteit 2%

De laatste tijd heb ik gebruikt git reflogom hiermee te helpen. Dit werkt meestal alleen als de samenvoeging gebeurde, en het was op uw machine.

git reflogkan iets als:

retourneren

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

De eerste regel geeft aan dat een samenvoeging is opgetreden. De 2e lijn is de tijd voor mijn samenvoeging. I simpelweg git reset --hard 43b6032om deze tak te dwingen te volgen van vóór de samenvoeging en handboek.


7

Met Modern Git kunt u:

git merge --abort

OUDERE SYNTAX:

git reset --merge

Old-school:

git reset --hard

Maar eigenlijk is het de moeite waard om te merken dat git merge --abortalleen equivalent is aan git reset --mergeAangezien MERGE_HEADis cadeau. Dit kan worden gelezen in de GIT-hulp voor het samenvoegen.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Na een mislukte samenvoeging, wanneer er geen MERGE_HEADis, kan de mislukte samenvoeging ongedaan worden gemaakt met git reset --merge, maar niet noodzakelijkerwijs met git merge --abort, , dus zijn ze niet alleen oude en nieuwe syntaxis voor hetzelfde .

Persoonlijk vind ik git reset --mergeVeel krachtiger en nuttiger in dagelijks werk, dus dat is degene die ik altijd gebruik.


8

Oké, de antwoorden die andere mensen hier gaf, waren dichtbij, maar het werkte niet. Dit is wat ik deed.

Doe dit …

git reset --hard HEAD^
git status

… gaf me de volgende status.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

Ik moest vervolgens dezelfde git resetopdracht nog meerdere keren typen. Elke keer dat ik dat deed, veranderde het bericht met één zoals je hieronder kunt zien.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

Op dit punt zag ik het statusbericht gewijzigd, dus ik probeerde een git pullte doen, en dat leek te werken:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

Zo lang verhaal kort, mijn opdrachten kwamen hierop neer:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull

9

Je moet je hoofd veranderen, niet de jouwe natuurlijk maar git hoofd ….

Dus voordat u antwoordt, laten we een achtergrond toevoegen, uitleggen wat is dit HEAD.

First of all what is HEAD?

HEADis gewoon een verwijzing naar de huidige commit (nieuwste) op de huidige tak.
Er kan op een bepaald moment slechts één HEADzijn. (Exclusief git worktree)

De inhoud van HEADwordt opgeslagen in .git/HEADen bevat de 40 bytes SHA-1 van de huidige commit.


detached HEAD

Als u niet op de laatste commit staat – wat betekent dat HEADwijst op een eerdere commit in de geschiedenis, het wordt detached HEAD.

Op de opdrachtregel ziet het er als volgt uit: SHA-1 in plaats van de naam van de vertakking, aangezien de HEADniet naar de punt van de huidige vertakking wijst

Een paar opties om te herstellen van een losgekoppeld HOOFD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Hiermee wordt een nieuwe branch uitgecheckt die naar de gewenste commit wijst.
Dit commando checkt uit naar een bepaalde commit.
Op dit punt kun je een branch maken en vanaf dit punt beginnen te werken.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>
# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Je kunt ook altijd de refloggebruiken.
git reflogzal elke wijziging weergeven die de HEADheeft bijgewerkt en het uitchecken van de gewenste reflog-invoer zal de HEADterugzetten naar deze vastlegging.

Telkens wanneer de kop wordt gewijzigd, is er een nieuw item in de reflog

git reflog
git checkout HEAD@{...}

Hiermee krijg je terug naar je gewenste commit


git reset --hard <commit_id>

“Verplaats” uw hoofd terug naar de gewenste commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Opmerking: (sinds git 2.7 )
    U kunt ook de git rebase --no-autostashook gebruiken.

git revert <sha-1>

“Ongedaan maken” de opgegeven commit of commit-assortiment.
De reset-opdracht wordt “ongedaan maken” van eventuele wijzigingen in de gegeven commit.
Een nieuwe commit met de ongedaan maken patch zal worden vastgelegd terwijl de oorspronkelijke commit ook in de geschiedenis zal blijven.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Dit schema illustreert welke opdracht wat doet.
Zoals u daar kunt zien reset && checkoutWijzig de HEAD.


10

Als u in het midden van het samenvoegen bent, kunt u het altijd afbreken

git merge --abort

11

U kunt git reflogom de vorige afrekening te vinden. Soms is dat een goede staat waar je terug wilt terugkeren naar.

Concreet,

$ git reflog
$ git reset --hard HEAD@{0}

12

Ik was in staat om dit probleem op te lossen met een enkele opdracht die niet inhoudt met het opzoeken van een commit-ID.

git reset --hard remotes/origin/HEAD

Het geaccepteerde antwoord werkte niet voor mij, maar dit commando leverde de resultaten op waar ik naar op zoek was.


Antwoord 13

Als je het nog niet hebt vastgelegd, kun je alleen

$ git checkout -f

Het zal de samenvoeging (en alles wat je deed) ongedaan maken.


Antwoord 14

Kreeg deze vraag ook op zoek om terug te keren naar de overeenkomst met de oorsprong (dwz GEEN commits voorafgaand aan de oorsprong). Na verder onderzoek te hebben gevonden, is er een reset-opdracht voor precies dat:

git reset --hard @{u}

Opmerking: @{u}is een afkorting voor origin/master. (En natuurlijk heb je die externe repository nodig om dit te laten werken.)


Antwoord 15

Als branches zijn samengevoegd en niet gepusht, dan zal het onderstaande git reset commando werken om de merge ongedaan te maken:

git reset --merge ORIG_HEAD

Antwoord 16

Het eenvoudigste antwoord is dat van odinho – Velmont

Doe eerst git reset --merge ORIG_HEAD

Voor degenen die willen resetten nadat wijzigingen zijn doorgevoerd, doe dit:
(Omdat dit het eerste bericht is dat wordt gezien voor vragen over git reset merge)

git push origin HEAD --force

Dit wordt zo gereset dat je de samengevoegde wijzigingen niet meer terugkrijgt na het verwijderen.


Antwoord 17

Je kunt slechts twee commando’s gebruiken om een samenvoeging terug te draaien of te herstarten door een specifieke vastlegging:

  1. git reset --hard commitHash(je moet de commit gebruiken die je wilt herstarten, bijv. 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force(Verzenden van de nieuwe lokale master branch naar origin/master)

Veel succes en ga je gang!


Antwoord 18

Voor een extra optie om naar te kijken, heb ik voornamelijk het hier beschreven vertakkingsmodel gevolgd: http://nvie.com/posts/a-successful-git-branching-model/en zijn als zodanig samengevoegd met --no-ff( niet snel vooruit) meestal.

Ik heb deze pagina net gelezen omdat ik per ongeluk een testbranch had samengevoegd in plaats van mijn releasebranch met master voor implementatie (website, master is wat live is). De testing branch heeft twee andere branches die ermee zijn samengevoegd en in totaal zijn er ongeveer zes commits.

Dus om de hele commit terug te draaien, had ik slechts één git reset --hard HEAD^nodig en het draaide de hele merge terug. Omdat de samenvoegingen niet snel doorgestuurd werden, was de samenvoeging een blokkade en een stap terug is “tak niet samengevoegd”.


Antwoord 19

Als je merge en de bijbehorende commits nog niet zijn gepusht, kun je altijd overschakelen naar een andere branch, de originele verwijderen en deze opnieuw maken.

Ik heb bijvoorbeeld per ongeluk een ontwikkel-branch in master samengevoegd en wilde dat ongedaan maken. Gebruik de volgende stappen:

git checkout develop
git branch -D master
git branch -t master origin/master

Voila! Meester bevindt zich in hetzelfde stadium als oorsprong, en je verkeerd samengevoegde staat is gewist.


Antwoord 20

Als je een opdrachtregeloplossing wilt, raad ik aan om gewoon het antwoord van MBO te gebruiken.

Als je een nieuweling bent, vind je de grafische benadering misschien leuk:

  1. Start gitk(vanaf de opdrachtregel, of klik met de rechtermuisknop in de bestandsbrowser als je die hebt)
  2. Je kunt daar gemakkelijk de merge-commit zien – het eerste knooppunt van boven met twee ouders
  3. Volg de link naar de eerste/linker ouder (die op je huidige branch voor de merge, meestal rood voor mij)
  4. Klik op de geselecteerde commit met de rechtermuisknop op “Vertakking resetten naar hier”, kies daar de harde reset

Antwoord 21

Strategie:maak een nieuwe tak van waaruit alles goed was.

Rationale:het terugdraaien van een samenvoeging is moeilijk. Er zijn te veel oplossingen, afhankelijk van veel factoren, zoals of je je merge hebt gecommit of gepusht of dat er nieuwe commits zijn sinds je merge. Je moet ook nog steeds een relatief diep begrip van git hebben om deze oplossingen aan jouw geval aan te passen. Als je blindelings enkele instructies volgt, kun je eindigen met een “lege samenvoeging” waar niets zal worden samengevoegd, en verdere samenvoegpogingen zullen ervoor zorgen dat Git je vertelt “Reeds up-to-date”.

Oplossing:

Stel dat u devwilt samenvoegen met feature-1.

  1. Zoek de revisie waarvan u de samenvoeging wilt ontvangen:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. Bekijk het (ga terug in de tijd):

    git checkout e5f6g7h8
    
  3. Maak van daaruit een nieuw filiaal en bekijk het:

    git checkout -b feature-1
    

Nu kunt u het samenvoegen opnieuw starten:

  1. Samenvoegen: git merge dev

  2. Los uw samenvoegconflicten op.

  3. Commit: git commit

  4. Als je tevreden bent met de resultaten, verwijder dan de oude branch: git branch --delete feature-1


Antwoord 22

Ik denk dat je git rebase -i [hash] [branch_name]kunt doen waarbij [hash]de identificerende hash is voor hoe ver terug je ook wilt terugspoelen plus één (of hoeveel commits je ook terug wilt) en verwijder dan de regels voor de commits in de editor die je niet meer wilt. Bewaar het bestand. Uitgang. Bidden. En het moet worden teruggespoeld. Mogelijk moet je een git reset --harddoen, maar op dit moment zou het goed moeten zijn. Je kunt dit ook gebruiken om specifieke commits uit een stapel te halen, als je ze niet in je geschiedenis wilt houden, maar dat kan je repository in een staat achterlaten die je waarschijnlijk niet wilt.


Antwoord 23

Maak gewoon een nieuwe branch en kies vervolgens de gewenste commits ervoor.

Het is veiliger en eenvoudiger dan resets zoals beschreven in veel antwoorden hierboven


Antwoord 24

Beantwoorden van de vraag “Maak een Git-samenvoeging ongedaan die nog niet is gepusht

Je kunt git reset --hard HEAD~1

gebruiken

Beschouw de volgende situatie waarin er 2 branches zijn masteren feature-1:


$ git log --graph --oneline --all

Git mergen

$ git merge feature-1

$ git log --graph --oneline --all

Git-samenvoeging ongedaan maken

$ git reset --hard HEAD~1

$ git log --graph --oneline --all


Antwoord 25

Als je de samenvoeging hebt uitgevoerd:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard

26

  1. Controleer eerst of u alles hebt gecommitteerd.

  2. Reset vervolgens uw repository naar de vorige werkstaat:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    Of gebruik --hard(Hiermee wordt alle lokale, niet toegewijde wijzigingen verwijderd! ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    Gebruik de hash die er was voordat je verergerde commit.

  3. Controleer of u zich wilt verbinden aan de bovenkant van de vorige juiste versie door:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    ...
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    ...
    
  4. Pas uw juiste commits toe aan de bovenkant van de juiste versie van uw repository door:

    • met behulp van Cherry-Pick (de wijzigingen die zijn geïntroduceerd door een aantal bestaande commits)

         git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • OF MY KERSER PICKEREN Het bereik van commits door:

      • Controleer eerst de juiste wijzigingen voordat u ze fuseert:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • Controleer eerst de juiste wijzigingen voordat u ze fuseert:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        Waar dit het bereik is van de juiste commits die u hebt gepleegd (exclusief verkeerd gepleegd samenvoeging).


27

  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

Dit werkte voor mij..!!


Antwoord 28

Als je merkt dat je onmiddellijk na het samenvoegen moet terugkeren en je niets anders hebt gedaan na de samenvoegpoging, kun je dit commando geven:
git reset --hard HEAD@{1}.

In wezen zal je samenvoeging shaverwijzen naar HEAD@{0}als er niets anders is vastgelegd na de samenvoeging en dus HEAD@{1}zal het vorige punt zijn vóór de samenvoeging.

Other episodes